<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">
	<meta http-equiv="pragma" content="no-cache" />
    <meta name="author" content="Jayli" />
	<meta name="keywords" content="淘宝UED 前端工程师 拔赤" />	
	<meta name="description" content="淘宝前端工程师拔赤，关注尖端前端技术，关注yui" />
	<meta http-equiv="imagetoolbar" content="no" />
	<meta name="title" content="拔赤的文章列表" />
    <title>yui3的node定时器</title>
    <link href="http://jayli.github.com/blog/atom.xml" rel="alternate" title="setImpl" type="application/atom+xml" />
    <link rel="stylesheet" href="http://jayli.github.com/blog/media/css/style.css">
    <link rel="stylesheet" href="http://jayli.github.com/blog/media/css/github.css">
	<style>
	</style>
    <script type="text/javascript" src="http://jayli.github.com/blog/media/js/highlight.pack.js"></script>
    <script type="text/javascript">
      hljs.initHighlightingOnLoad();
    </script>
	<!--[if lte IE 8]>
	<script src="http://a.tbcdn.cn/apps/lottery/00023/index-v3/js/html5.js"></script>
	<![endif]-->
	<meta name="baidu-tc-verification" content="afb6c9df553ef3493d9ee65263df0d55" />
	<script src="http://siteapp.baidu.com/static/webappservice/uaredirect.js" type="text/javascript"></script><script type="text/javascript">uaredirect("http://m.zoojs.org", "http://jayli.github.com/blog");</script>
  </head>
  <body>
    <div id="container">
      <div id="main" role="main">
        <header>
        <h1>yui3的node定时器</h1>
        </header>
        <nav>
        <span><a title="home page" class="" href="/blog/index.html">home</a></span>
        <span><a title="tags" class="" href="/blog/tags.html">tags</a></span>
        <span><a title="about" class="" href="/blog/about.html">about me</a></span>
        <span><a title="flickr" class="" href="http://www.flickr.com/photos/lijing00333">flickr</a></span>
        <span><a title="blogroll" class="" href="/blog/links.html">links</a></span>
        <span><a title="projects" class="" href="/blog/projects.html">projects</a></span>
        <span><a title="subscribe me" class="" href="/blog/atom.xml">feed</a></span>
        </nav>
        <article class="content">
        <section class="post">
<p>jquery有一个插件叫Timer，很有意思，咱来实现一个简版的yui3的node timer。但还是应当首先交代下yui3的node扩展的一些事情，yui3 beta在实现上和pre版相比有很大不同，其中就包括yui原生元素的扩展方式的实现，之前在yui3还是pre的时候写过一篇yui3的链式调用的文章，阐述如何给原生的Node增加自定义方法，也就是实现了一个类似Y.Node.get(‘#id’).fuck()。在pre版需要使用 Node.addDOMMethod方法添加声明，而在yui3beta版这个方法就被去掉了，干脆直接通过在Y.Node.prototype上挂载新方法来实现扩展，这样确实方便了许多，自然，yui对Node的保护也变的较为脆弱，岂不是只通过Y.Node.prototype就可以重载原生的接口？但yui3内在的元素比如node和dom之间的继承的实现仍然采用了pre的思路，只是将那个addDomMethod改成了语义更通用的 Y.Node.importMethod（需要扩展的不只有Dom节点）。</p>

<p>再来看node定时器的实现，这里我要实现两个div宽度增长这样一个功能，而且两个div之间的行为不应当相互影响，就类似两个线程同时执行不相互影响。直接裸写代码就应当这样。这里有一个需要注意的地方，就是短时间连续的dom操作可能会造成浏览器假死，就是说实际dom操作已经完成，但在页面上看不到效果，原因在这里。</p>

<p>grow函数的实现：</p>

<pre><code>var grow = function(id){
    setTimeout(function(){
        var _width = Number(Y.Node.get(‘#’+id).getStyle(‘width’).replace(‘px’,”));
        if(_width &gt;= 500)return;
        Y.Node.get(‘#’+id).setStyle(‘width’,(_width+1).toString()+’px’).
        set(‘innerHTML’,(_width+1).toString());
        setTimeout(arguments.callee,0);
    },0);
};
</code></pre>

<p>这样就可以看到效果了，例子在这里</p>

<p>http://www.uedmagazine.com/test/execthreads.html</p>

<p>然而这里还是需要手动对相邻的dom操作做settimeout的hack，这里实现了一个everyTime的扩展，可以通过</p>

<pre><code>Y.Node.get('#id').everyTime(10,function(node){
    //your code here
},false);
</code></pre>

<p>这样就将settimeout的方法的hack封装进node中，不用写那些晦涩难懂的settimeout和callee了。</p>

<p>实现的代码是这样的：</p>

<pre><code>YUI.add(‘node-timer’,function(Y){
    Y.Node.prototype.everyTime = function() {
        var node = this;
        node._ttime = arguments[0];
        if(typeof arguments[1] == ‘function’){
            node._timer_f = arguments[1];
        }else {
            throw new TypeError(“function must be required”);
            return false;
        }
        var _run_now = (arguments[2] == false)?false:true;
        if(_run_now){
            node.startTimer();
        }
    };
    Y.Node.prototype.stopTimer = function(){
        var node = this;
        setTimeout(function(){
            if(!node._timer)return false;
            clearTimeout(node._timer);
        },0);
    };
    Y.Node.prototype.startTimer = function(){
        var node = this;
        node._timer = setTimeout(function(){
            if(node._timer_f(node) == false){
                clearTimeout(node._timer);
                return false;
            }
            node._timer = setTimeout(arguments.callee,node._ttime);
        },node._ttime);
    };
},”,{requires:['node']});
</code></pre>

<p>例子在这里：</p>

<p>http://www.uedmagazine.com/test/yui3NodeTimer.html</p>

<p>用法：</p>

<ul>
<li>node.every(time,foo,flag)</li>
<li>time：相邻操作的间隔时间</li>
<li>foo：foo(node)，每次操作的回调函数，回调参数是node本身，当函数返回false的时候停止循环</li>
<li>flag：true，立即执行，false，不立即执行，默认为true</li>
</ul>


<p>node.stopTimer()</p>

<p>停止执行最后的一次timer，这里多次执行startTimer的时候会对node的timer进行叠加，并不去重，这个以后在说</p>

<p>node.startTimer()</p>

<p>开始执行，这里多次开始会叠加执行</p>

<p>to be continue…</p>

</section>
<section class="meta">

<!--span class="tags">
  tagged by 
  
</span-->

<span class="time">
  posted at <time datetime="2009-12-01">2009-12-01</time>
</span>
</section>

<section class="comment">
<div id="disqus_thread"></div>
<script type="text/javascript">
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = 'jayliblog'; // required: replace example with your forum shortname
	var disqus_identifier = 'urn:uuid:60a01f57-9663-4c5f-8a37-bdefdd05f33b';

    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</section>


        </article>
      </div>
    </div> <!--! end of #container -->
  </body>
</html>
